#ifndef _RTL8367C_ASICDRV_ACL_H_
#define _RTL8367C_ASICDRV_ACL_H_

#include "rtl8367c_asicdrv.h"

#define RTL8367C_ACLRULENO 96

#define RTL8367C_ACLRULEMAX (RTL8367C_ACLRULENO - 1)
#define RTL8367C_ACLRULEFIELDNO 8
#define RTL8367C_ACLTEMPLATENO 5
#define RTL8367C_ACLTYPEMAX (RTL8367C_ACLTEMPLATENO - 1)

#define RTL8367C_ACLRULETBLEN 9
#define RTL8367C_ACLACTTBLEN 4
#define RTL8367C_ACLRULETBADDR(type, rule) ((type << 6) | rule)
#define RTL8367C_ACLRULETBADDR2(type, rule) ((type << 5) | (rule + 64))

#define ACL_ACT_CVLAN_ENABLE_MASK 0x1
#define ACL_ACT_SVLAN_ENABLE_MASK 0x2
#define ACL_ACT_PRIORITY_ENABLE_MASK 0x4
#define ACL_ACT_POLICING_ENABLE_MASK 0x8
#define ACL_ACT_FWD_ENABLE_MASK 0x10
#define ACL_ACT_INTGPIO_ENABLE_MASK 0x20

#define RTL8367C_ACLRULETAGBITS 5

#define RTL8367C_ACLRANGENO 16

#define RTL8367C_ACLRANGEMAX (RTL8367C_ACLRANGENO - 1)

#define RTL8367C_ACL_PORTRANGEMAX (0xFFFF)
#define RTL8367C_ACL_ACT_TABLE_LEN (4)

enum ACLTCAMTYPES
{
    CAREBITS = 0,
    DATABITS
};

typedef enum aclFwdAct
{
    RTL8367C_ACL_FWD_MIRROR = 0,
    RTL8367C_ACL_FWD_REDIRECT,
    RTL8367C_ACL_FWD_MIRRORFUNTION,
    RTL8367C_ACL_FWD_TRAP,
} rtl8367c_aclFwd_t;

enum ACLFIELDTYPES
{
    ACL_UNUSED,
    ACL_DMAC0,
    ACL_DMAC1,
    ACL_DMAC2,
    ACL_SMAC0,
    ACL_SMAC1,
    ACL_SMAC2,
    ACL_ETHERTYPE,
    ACL_STAG,
    ACL_CTAG,
    ACL_IP4SIP0 = 0x10,
    ACL_IP4SIP1,
    ACL_IP4DIP0,
    ACL_IP4DIP1,
    ACL_IP6SIP0WITHIPV4 = 0x20,
    ACL_IP6SIP1WITHIPV4,
    ACL_IP6DIP0WITHIPV4 = 0x28,
    ACL_IP6DIP1WITHIPV4,
    ACL_VIDRANGE = 0x30,
    ACL_IPRANGE,
    ACL_PORTRANGE,
    ACL_FIELD_VALID,
    ACL_FIELD_SELECT00 = 0x40,
    ACL_FIELD_SELECT01,
    ACL_FIELD_SELECT02,
    ACL_FIELD_SELECT03,
    ACL_FIELD_SELECT04,
    ACL_FIELD_SELECT05,
    ACL_FIELD_SELECT06,
    ACL_FIELD_SELECT07,
    ACL_FIELD_SELECT08,
    ACL_FIELD_SELECT09,
    ACL_FIELD_SELECT10,
    ACL_FIELD_SELECT11,
    ACL_FIELD_SELECT12,
    ACL_FIELD_SELECT13,
    ACL_FIELD_SELECT14,
    ACL_FIELD_SELECT15,
    ACL_TCPSPORT = 0x80,
    ACL_TCPDPORT,
    ACL_TCPFLAG,
    ACL_UDPSPORT,
    ACL_UDPDPORT,
    ACL_ICMPCODETYPE,
    ACL_IGMPTYPE,
    ACL_SPORT,
    ACL_DPORT,
    ACL_IP4TOSPROTO,
    ACL_IP4FLAGOFF,
    ACL_TCNH,
    ACL_CPUTAG,
    ACL_L2PAYLOAD,
    ACL_IP6SIP0,
    ACL_IP6SIP1,
    ACL_IP6SIP2,
    ACL_IP6SIP3,
    ACL_IP6SIP4,
    ACL_IP6SIP5,
    ACL_IP6SIP6,
    ACL_IP6SIP7,
    ACL_IP6DIP0,
    ACL_IP6DIP1,
    ACL_IP6DIP2,
    ACL_IP6DIP3,
    ACL_IP6DIP4,
    ACL_IP6DIP5,
    ACL_IP6DIP6,
    ACL_IP6DIP7,
    ACL_TYPE_END
};

struct acl_rule_smi_st
{
    rtk_uint16 rule_info;
    rtk_uint16 field[RTL8367C_ACLRULEFIELDNO];
};

struct acl_rule_smi_ext_st
{
    rtk_uint16 rule_info;
};

typedef struct ACLRULESMI
{
    struct acl_rule_smi_st care_bits;
    rtk_uint16 valid : 1;
    struct acl_rule_smi_st data_bits;

    struct acl_rule_smi_ext_st care_bits_ext;
    struct acl_rule_smi_ext_st data_bits_ext;
} rtl8367c_aclrulesmi;

struct acl_rule_st
{
    rtk_uint16 active_portmsk : 11;
    rtk_uint16 type : 3;
    rtk_uint16 tag_exist : 5;
    rtk_uint16 field[RTL8367C_ACLRULEFIELDNO];
};

typedef struct ACLRULE
{
    struct acl_rule_st data_bits;
    rtk_uint16 valid : 1;
    struct acl_rule_st care_bits;
} rtl8367c_aclrule;

typedef struct rtl8367c_acltemplate_s
{
    rtk_uint8 field[8];
} rtl8367c_acltemplate_t;

typedef struct acl_act_s
{
    rtk_uint16 cvidx_cact : 7;
    rtk_uint16 cact : 2;
    rtk_uint16 svidx_sact : 7;
    rtk_uint16 sact : 2;

    rtk_uint16 aclmeteridx : 7;
    rtk_uint16 fwdpmask : 11;
    rtk_uint16 fwdact : 2;

    rtk_uint16 pridx : 7;
    rtk_uint16 priact : 2;
    rtk_uint16 gpio_pin : 4;
    rtk_uint16 gpio_en : 1;
    rtk_uint16 aclint : 1;

    rtk_uint16 cact_ext : 2;
    rtk_uint16 fwdact_ext : 1;
    rtk_uint16 tag_fmt : 2;
} rtl8367c_acl_act_t;

typedef struct acl_rule_union_s
{
    rtl8367c_aclrule aclRule;
    rtl8367c_acl_act_t aclAct;
    rtk_uint32 aclActCtrl;
    rtk_uint32 aclNot;
} rtl8367c_acl_rule_union_t;

extern ret_t rtl8367c_setAsicAcl(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicAcl(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 enabled);
extern ret_t rtl8367c_getAsicAclUnmatchedPermit(rtk_uint32 port, rtk_uint32 *pEnabled);
extern ret_t rtl8367c_setAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule);
extern ret_t rtl8367c_getAsicAclRule(rtk_uint32 index, rtl8367c_aclrule *pAclRule);
extern ret_t rtl8367c_setAsicAclNot(rtk_uint32 index, rtk_uint32 _not);
extern ret_t rtl8367c_getAsicAclNot(rtk_uint32 index, rtk_uint32 *pNot);
extern ret_t rtl8367c_setAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType);
extern ret_t rtl8367c_getAsicAclTemplate(rtk_uint32 index, rtl8367c_acltemplate_t *pAclType);
extern ret_t rtl8367c_setAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct);
extern ret_t rtl8367c_getAsicAclAct(rtk_uint32 index, rtl8367c_acl_act_t *pAclAct);
extern ret_t rtl8367c_setAsicAclActCtrl(rtk_uint32 index, rtk_uint32 aclActCtrl);
extern ret_t rtl8367c_getAsicAclActCtrl(rtk_uint32 index, rtk_uint32 *aclActCtrl);
extern ret_t rtl8367c_setAsicAclPortRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperPort, rtk_uint32 lowerPort);
extern ret_t rtl8367c_getAsicAclPortRange(rtk_uint32 index, rtk_uint32 *pType, rtk_uint32 *pUpperPort, rtk_uint32 *pLowerPort);
extern ret_t rtl8367c_setAsicAclVidRange(rtk_uint32 index, rtk_uint32 type, rtk_uint32 upperVid, rtk_uint32 lowerVid);
extern ret_t rtl8367c_getAsicAclVidRange(rtk_uint32 index, rtk_uint32 *pType, rtk_uint32 *pUpperVid, rtk_uint32 *pLowerVid);
extern ret_t rtl8367c_setAsicAclIpRange(rtk_uint32 index, rtk_uint32 type, ipaddr_t upperIp, ipaddr_t lowerIp);
extern ret_t rtl8367c_getAsicAclIpRange(rtk_uint32 index, rtk_uint32 *pType, ipaddr_t *pUpperIp, ipaddr_t *pLowerIp);
extern ret_t rtl8367c_setAsicAclGpioPolarity(rtk_uint32 polarity);
extern ret_t rtl8367c_getAsicAclGpioPolarity(rtk_uint32 *pPolarity);

#endif /*_RTL8367C_ASICDRV_ACL_H_*/
